﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Net;
using System.IO;
using System.Threading;
using System.Collections;
using Medicalsystem.Update.UpdateServer;
using ICSharpCode.SharpZipLib.Zip;
using System.Xml;
using System.Configuration;
namespace Medicalsystem.Update
{
    public partial class FrmUpdate : Form
    {
        /// <summary>
        /// 更新服务
        /// </summary>
        UpdateService updateService = new UpdateService();
        string MainAppLocalVersion = System.Configuration.ConfigurationSettings.AppSettings.Get("MainAppLocalVersion");

        /// <summary>
        /// 当前应用程序编号
        /// </summary>
        string appID = Properties.Settings.Default.MainAppID;

        /// <summary>
        /// 主进程是否运行
        /// </summary>
        bool IsAppRun = false;

        string serverVer = "";
        /// <summary>
        /// 构造函数
        /// </summary>
        public FrmUpdate()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 设置图片
        /// </summary>
        private void SetUI()
        {
            this.Text = Properties.Settings.Default.UpdateAppName;
            try
            {
                if (File.Exists(Properties.Settings.Default.UpdateAppImage))
                {
                    pictureBox1.Image = Image.FromFile(Properties.Settings.Default.UpdateAppImage);
                }
            }
            catch
            {
                pictureBox1.Image = Properties.Resources.background;
            }
        }

        /// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmUpdate_Load(object sender, System.EventArgs e)
        {
            updateService.Url = Properties.Settings.Default.UpdateServiceUrl;
            serverVer = updateService.GetLastVersion(appID);
            SetUI();
            IsAppRun = IsMainAppRun();
            if (Properties.Settings.Default.IsAutoUpdate)
            {
                btnFinish.Visible = false;
                btnCancel.Visible = false;
                btnFinish_Click(this.btnFinish, e);
            }
            else
            {
                Hashtable htUpdateFile = new Hashtable();
                ServerData.T_VERSION_FILEDataTable fileData = updateService.GetLastUpdateFiles(serverVer);
                foreach (ServerData.T_VERSION_FILERow dr in fileData.Rows)
                {
                    string[] fileArray = new string[2];
                    fileArray[0] = dr.FILENAME;
                    fileArray[1] = dr.FILEVERSION;
                    lvUpdateList.Items.Add(new ListViewItem(fileArray));
                }
                btnFinish.Visible = true;
                btnCancel.Visible = true;
            }
        }

        /// <summary>
        /// 检查是否有更新
        /// </summary>
        public bool CheckUpdate()
        {
            serverVer = updateService.GetLastVersion(appID);

            string local = MainAppLocalVersion;
            if (!string.IsNullOrEmpty(serverVer) && serverVer == MainAppLocalVersion)
            {
                return false;
            }


            return true;
        }

        /// <summary>
        /// 取消更新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, System.EventArgs e)
        {
            Environment.Exit(0);
            Application.ExitThread();
            Application.Exit();
        }

        private delegate void DelegateDownUpdateFile();

        /// <summary>
        /// 委托更新
        /// </summary>
        private void ThreadUpdate()
        {
            DelegateDownUpdateFile downLoadUpdateFile = new DelegateDownUpdateFile(UpdateAppFile);
            this.Invoke(downLoadUpdateFile);
        }


        /// <summary>
        /// 更新文件
        /// </summary>
        private void UpdateAppFile()
        {

            string updateFilePackageName = updateService.GetLastUpdatePackageName(serverVer);
            string baseDiretory = Application.StartupPath + "\\";
            #region 清理主进程
            if (IsAppRun && Properties.Settings.Default.IsRebootMainProcess)
            {
                string mainAppExe = Properties.Settings.Default.MainProcessFile;
                Process[] allProcess = Process.GetProcesses();

                foreach (Process p in allProcess)
                {
                    if (p.ProcessName.ToLower() + ".exe" == mainAppExe.ToLower())
                    {
                        for (int i = 0; i < p.Threads.Count; i++)
                        {
                            p.Threads[i].Dispose();
                        }
                        p.Kill();
                    }
                }
            }
            #endregion
            #region 下载文件
            WebClient wcClient = new WebClient();
            string updateFileUrl = updateService.GetLastFileUrl(serverVer);
            long fileLength = 0;

            WebRequest webReq = WebRequest.Create(updateFileUrl);
            WebResponse webRes = webReq.GetResponse();
            fileLength = webRes.ContentLength;

            lbState.Text = "正在下载更新文件,请稍后...";
            pbDownFile.Value = 0;
            pbDownFile.Maximum = (int)fileLength;

            try
            {
                Stream srm = webRes.GetResponseStream();
                StreamReader srmReader = new StreamReader(srm);
                byte[] bufferbyte = new byte[fileLength];
                int allByte = (int)bufferbyte.Length;
                int startByte = 0;
                while (fileLength > 0)
                {
                    Application.DoEvents();
                    int downByte = srm.Read(bufferbyte, startByte, allByte);
                    if (downByte == 0) { break; };
                    startByte += downByte;
                    allByte -= downByte;
                    pbDownFile.Value += downByte;
                    float part = (float)startByte / 1024;
                    float total = (float)bufferbyte.Length / 1024;
                    int percent = Convert.ToInt32((part / total) * 100);
                }
                FileStream fs = new FileStream(baseDiretory + updateFilePackageName, FileMode.OpenOrCreate, FileAccess.Write);
                fs.Write(bufferbyte, 0, bufferbyte.Length);
                srm.Close();
                srmReader.Close();
                fs.Close();
            }
            catch (WebException ex)
            {
                MessageBox.Show("更新文件下载失败！" + ex.Message.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            #endregion
            #region 解压文件

            UnZipFile(baseDiretory + updateFilePackageName, baseDiretory);
            #endregion
            #region 删除临时文件
            if (Properties.Settings.Default.IsDeleteTmpZip)
            {
                try
                {
                    System.IO.File.Delete(baseDiretory + updateFilePackageName);
                }
                catch
                {

                    MessageBox.Show("删除临时文件出错。");
                }
            }



            #endregion
            #region 修改版本号
            SetConfig("MainAppLocalVersion", serverVer);
            Properties.Settings.Default.Save();
            #endregion
            #region 重启主进程
            Thread.Sleep(1000);
            RunMain(baseDiretory + Properties.Settings.Default.MainProcessFile);
            #endregion
            Environment.Exit(20000);
        }
        public void RunMain(string FileName)
        {

            if (!IsMainAppRun() && Properties.Settings.Default.IsRebootMainProcess)
            {
                try
                {
                    Process p = new Process();
                    p.StartInfo.FileName = FileName;
                    p.Start();
                }
                catch
                {

                    MessageBox.Show("主进程目录及名称配置不正确。");
                }

            }

        }
        /// <summary>
        /// 解压
        /// </summary>
        /// <param name="zipFile"></param>
        /// <param name="targetPath"></param>
        public void UnZipFile(string zipFile, string targetPath)
        {
            try
            {
                FastZip fastZip = new FastZip();
                fastZip.ExtractZip(zipFile, targetPath, "");
            }
            catch (Exception ex)
            {
                MessageBox.Show("解压出错:" + ex.Message.ToString());
            }
        }



        //点击完成复制更新文件到应用程序目录
        private void btnFinish_Click(object sender, System.EventArgs e)
        {
            try
            {

                Thread threadDown = new Thread(ThreadUpdate);
                threadDown.IsBackground = true;
                threadDown.Start();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
        }

        //判断主应用程序是否正在运行
        public bool IsMainAppRun()
        {
            string mainAppExe = Properties.Settings.Default.MainProcessFile;
            bool isRun = false;
            Process[] allProcess = Process.GetProcesses();
            foreach (Process p in allProcess)
            {

                if (p.ProcessName.ToLower() + ".exe" == mainAppExe.ToLower())
                {
                    isRun = true;
                    //break;
                }
            }
            return isRun;
        }

        private void SetConfig(string key, string value)
        {

            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            if (config.AppSettings.Settings[key] != null)
                config.AppSettings.Settings[key].Value = value;
            else
                config.AppSettings.Settings.Add(key, value);

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }
    }
}
